//-------------------------------------初始化----------------------------
// 写一个可以在GPU上运行的程序需要：编译-链接->程序
// webgl需要提供：裁剪空间中的坐标值和颜色值，一个顶点着色器提供裁剪空间坐标值，一个片段着色器提供颜色值
// 获取 WebGL 上下文
var canvas = document.querySelector('#c');
var gl = canvas.getContext('webgl');

// 创建着色器方法
function createShader(gl, type, source) {
  var shader = gl.createShader(type); // 创建着色器对象，type为着色器类型（gl.VERTEX_SHADER 或 gl.FRAGMENT_SHADER）
  gl.shaderSource(shader, source); // 提供数据源
  gl.compileShader(shader); // 编译着色器
  var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
  if (success) {
    return shader; // 编译成功返回着色器对象
  }
  console.log(gl.getShaderInfoLog(shader)); // 打印编译错误信息
  gl.deleteShader(shader);
}

// 加载着色器源代码
var vertexShaderSource = document.querySelector('#vertex-shader-2d').text;
var fragmentShaderSource = document.querySelector('#fragment-shader-2d').text;

// 编译着色器
var vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);

// 创建着色器程序
function createProgram(gl, vertexShader, fragmentShader) {
  var program = gl.createProgram();
  gl.attachShader(program, vertexShader); // 附加顶点着色器
  gl.attachShader(program, fragmentShader); // 附加片段着色器
  gl.linkProgram(program); // 链接程序
  var success = gl.getProgramParameter(program, gl.LINK_STATUS);
  if (success) {
    return program;
  }
  console.log(gl.getProgramInfoLog(program)); // 打印链接错误信息
  gl.deleteProgram(program);
}

// 链接着色器程序（调用 createProgram 函数链接顶点着色器和片段着色器，生成一个完整的着色器程序）
var program = createProgram(gl, vertexShader, fragmentShader);

// 获取属性位置（获取顶点着色器中 a_position 属性的位置，用于后续绑定缓冲区数据）
var positionAttributeLocation = gl.getAttribLocation(program, 'a_position');

// 创建并绑定缓冲区
var positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

// 填充缓冲区数据（将顶点数据填充到缓冲区中，使用 gl.STATIC_DRAW 表示数据不会频繁更改）
var positions = [0, 0, 0, 0.5, 0.7, 0];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

//----------------------------渲染------------------------------
// 启用属性
gl.enableVertexAttribArray(positionAttributeLocation);

// 指定从缓冲中读取数据的方式
//（告诉 WebGL 如何从缓冲区中读取数据：
// 2：每个顶点由 2 个值组成（x, y）。
// gl.FLOAT：数据类型为浮点数。
// false：不归一化数据。
// 0：步长（stride），表示数据是紧密排列的。
// 0：偏移量（offset），表示从缓冲区的起始位置读取
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

// 使用程序
gl.useProgram(program);

// 设置视口和清除画布
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); //告诉WebGL裁剪空间的 -1 -> +1 分别对应到x轴的 0 -> gl.canvas.width 和y轴的 0 -> gl.canvas.height。
gl.clearColor(0, 0, 0, 0); // 清除画布，分别对应 r, g, b, alpha （红，绿，蓝，透明度）值
gl.clear(gl.COLOR_BUFFER_BIT);

// 绘制三角形：
// gl.TRIANGLES：绘制模式，表示绘制三角形。
// 0：从第一个顶点开始。
// 3：绘制 3 个顶点。顶点着色器将运行三次， 第一次运行将会从位置缓冲中读取前两个值赋给属性值a_position.x和a_position.y。 第二次运行a_position.xy将会被赋予后两个值，最后一次运行将被赋予最后两个值。
gl.drawArrays(gl.TRIANGLES, 0, 3);
